/**
 * Fabric.js的辅助函数集合
 */
import * as fabricjs from 'fabric';
const { fabric } = fabricjs;
import { v4 as uuidv4 } from 'uuid';

/**
 * 创建一个具有唯一ID的Fabric对象
 * @param {fabric.Object} obj - Fabric对象
 * @param {string} objectType - 对象类型，用于命名
 * @returns {fabric.Object} 带有ID和名称的对象
 */
export function createUniqueObject(obj, objectType = 'object') {
    obj.set({
        id: uuidv4(),
        name: `${objectType}-${Date.now()}`
    });
    return obj;
}

/**
 * 获取对象在组中的位置
 * @param {fabric.Object} obj - 要检查的对象
 * @param {fabric.Group} group - 组对象
 * @returns {Object} 对象在组中的位置 {x, y}
 */
export function getObjectPositionInGroup(obj, group) {
    const matrix = group.calcTransformMatrix();
    const options = fabric.util.qrDecompose(matrix);

    return {
        x: obj.left - group.left + group.width / 2,
        y: obj.top - group.top + group.height / 2
    };
}

/**
 * 将SVG字符串转换为Fabric对象
 * @param {string} svgString - SVG字符串
 * @returns {Promise<fabric.Object>} Fabric对象
 */
export function svgToFabricObject(svgString) {
    return new Promise((resolve, reject) => {
        fabric.loadSVGFromString(svgString, (objects, options) => {
            if (!objects || objects.length === 0) {
                reject(new Error('无法加载SVG'));
                return;
            }

            if (objects.length === 1) {
                resolve(objects[0]);
            } else {
                const group = new fabric.Group(objects);
                resolve(group);
            }
        });
    });
}

/**
 * 将Fabric对象转换为SVG
 * @param {fabric.Object} object - Fabric对象
 * @returns {string} SVG字符串
 */
export function fabricObjectToSVG(object) {
    const tempCanvas = new fabric.StaticCanvas(null, {
        width: object.width * object.scaleX,
        height: object.height * object.scaleY
    });

    // 克隆对象并调整位置
    const clonedObj = object.clone();
    clonedObj.set({
        left: tempCanvas.width / 2,
        top: tempCanvas.height / 2,
        originX: 'center',
        originY: 'center'
    });

    tempCanvas.add(clonedObj);

    // 获取SVG字符串并清理Canvas
    const svgString = tempCanvas.toSVG();
    tempCanvas.dispose();

    return svgString;
}

/**
 * 对Canvas上的对象进行分组
 * @param {fabric.Canvas} canvas - Fabric Canvas实例
 * @param {Array<fabric.Object>} objects - 要分组的对象数组
 * @returns {fabric.Group} 创建的组对象
 */
export function groupObjects(canvas, objects) {
    if (!objects || objects.length === 0) {
        return null;
    }

    // 从Canvas中移除对象
    objects.forEach(obj => canvas.remove(obj));

    // 创建组
    const group = new fabric.Group(objects, {
        id: uuidv4(),
        name: `group-${Date.now()}`
    });

    canvas.add(group);
    canvas.setActiveObject(group);
    canvas.renderAll();

    return group;
}

/**
 * 解散组
 * @param {fabric.Canvas} canvas - Fabric Canvas实例
 * @param {fabric.Group} group - 要解散的组
 * @returns {Array<fabric.Object>} 解散后的对象数组
 */
export function ungroupObjects(canvas, group) {
    if (!group || group.type !== 'group') {
        return [];
    }

    // 获取组中的对象
    const items = group._objects;
    const groupLeft = group.left;
    const groupTop = group.top;

    // 从Canvas中移除组
    canvas.remove(group);

    // 将组中的每个对象添加到Canvas
    const objects = [];
    items.forEach(obj => {
        // 计算对象的新位置
        obj.left += groupLeft;
        obj.top += groupTop;
        obj.setCoords();

        // 如果对象没有ID，添加一个
        if (!obj.id) {
            obj.id = uuidv4();
        }

        canvas.add(obj);
        objects.push(obj);
    });

    // 渲染Canvas
    canvas.renderAll();

    return objects;
}

/**
 * 将对象对齐到Canvas的边缘或中心
 * @param {fabric.Canvas} canvas - Fabric Canvas实例
 * @param {fabric.Object} object - 要对齐的对象
 * @param {string} alignTo - 对齐位置 ('left', 'center', 'right', 'top', 'middle', 'bottom')
 */
export function alignObject(canvas, object, alignTo) {
    if (!object || !canvas) return;

    const canvasWidth = canvas.getWidth();
    const canvasHeight = canvas.getHeight();

    switch (alignTo) {
        case 'left':
            object.set({ left: 0 + object.getScaledWidth() / 2 });
            break;
        case 'center':
            object.set({ left: canvasWidth / 2 });
            break;
        case 'right':
            object.set({ left: canvasWidth - object.getScaledWidth() / 2 });
            break;
        case 'top':
            object.set({ top: 0 + object.getScaledHeight() / 2 });
            break;
        case 'middle':
            object.set({ top: canvasHeight / 2 });
            break;
        case 'bottom':
            object.set({ top: canvasHeight - object.getScaledHeight() / 2 });
            break;
    }

    object.setCoords();
    canvas.renderAll();
}

/**
 * 将画布状态转换为JSON
 * @param {fabric.Canvas} canvas - Fabric Canvas实例
 * @param {Array<string>} additionalProps - 要包含的额外属性
 * @returns {Object} 画布状态的JSON对象
 */
export function canvasToJson(canvas, additionalProps = []) {
    const defaultProps = ['id', 'name'];
    const props = [...defaultProps, ...additionalProps];
    return canvas.toJSON(props);
}

/**
 * 从JSON恢复画布状态
 * @param {fabric.Canvas} canvas - Fabric Canvas实例
 * @param {Object} json - 画布状态的JSON对象
 * @returns {Promise<void>}
 */
export function loadCanvasFromJson(canvas, json) {
    return new Promise((resolve) => {
        canvas.loadFromJSON(json, () => {
            canvas.renderAll();
            resolve();
        });
    });
}
